/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package merlion.crm.sopm.entity;

import merlion.crm.slcm.entity.Customer;
import java.io.Serializable;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import merlion.common.entity.Staff;
import merlion.common.util.Consts;
import merlion.scm.lcm.entity.DeliveryOrder;

/**
 *
 * @author Yuwei
 */
@Entity
public class SalesOrder implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String salesOrderIdStr;
    private Timestamp salesOrderDate;
    private Timestamp leadTime;
    private Timestamp shipDate;
    private String salesOrderStatus;
    private String dateStr;
    private Boolean currency;
    private Boolean paymentMode;
    private Double memberDiscount;
    private Double orderDiscount;
    private Double specialDiscount;
    private Double subtotal;
    private Double tax;
    private Double total;
    private String comments;
    private Boolean freightOnBoard;
    private Boolean fullShipment;
    private Boolean cancelled; // TRUE FOR CANCELLED SALES ORDER
    @ManyToOne(targetEntity = Customer.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
    private Customer customer;
    @OneToMany(targetEntity=DeliveryOrder.class, cascade={CascadeType.PERSIST,CascadeType.MERGE}, fetch=FetchType.EAGER)
    private Collection<DeliveryOrder> deliveryOrders;
    @OneToOne(targetEntity = PurchaseOrder.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER, mappedBy = "salesOrder")
    private PurchaseOrder purchaseOrder;
    @ManyToOne(targetEntity = Staff.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
    private Staff customerExecutive;
    @OneToMany(targetEntity=ItemLine.class, cascade={CascadeType.PERSIST,CascadeType.MERGE}, fetch=FetchType.EAGER)
    private Collection<ItemLine> itemLines;
    private static final SimpleDateFormat formatter = new SimpleDateFormat("MMMMM dd, yyyy");
    
    // for mrp
    private Boolean promotion;

    public SalesOrder() {
        freightOnBoard = true;
        fullShipment  = true;
        currency = true;
        paymentMode = true;
        deliveryOrders = new ArrayList<DeliveryOrder>();
        salesOrderDate = new Timestamp(new Date().getTime());
        dateStr = convertToDateFormat(salesOrderDate);
        customer = new Customer();
        cancelled = Boolean.FALSE;
        salesOrderStatus = Consts.ORDER_INITIATED;
        salesOrderIdStr = "";
        // for mrp
        promotion = Boolean.FALSE;
    }
    
    private String convertToDateFormat(Timestamp timeStamp){
        return formatter.format((java.util.Date) timeStamp);
    }

//    public void create(PurchaseOrder purchaseOrder, Staff customerExecutive, String comments){
//        this.setCustomer(purchaseOrder.getCustomer());
//        this.setOrderItems(purchaseOrder.getOrderItems());
//        Date today = new Date();
//        this.setSalesOrderDate(new Timestamp(today.getTime()));
//        this.setIndicativeLeadTime(purchaseOrder.getIndicativeLeadTime());
//        this.setShipDate(new Timestamp(getSalesOrderDate().getTime() + getIndicativeLeadTime().getTime()));
//        this.setSalesOrderStatus(Consts.ORDER_CREDITCHECKING);
//        this.setCurrency(purchaseOrder.getCurrency());
//        this.setCustomerExecutive(customerExecutive);
//        this.setComments(comments);     
//    }
    public void create(Timestamp salesOrderDate, Timestamp leadTime,
            Timestamp shipDate, String salesOrderStatus, Boolean currency, String comments) {
        this.setComments(comments);
        this.setSalesOrderDate(salesOrderDate);
        this.setLeadTime(leadTime);
        this.setShipDate(shipDate);
        this.setSalesOrderStatus(salesOrderStatus);
        this.setCurrency(currency);
    }

    public Double getTotalOrder() {

        return 0.0;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getDateStr() {
        return dateStr;
    }

    public void setDateStr(String dateStr) {
        this.dateStr = dateStr;
    }

    public String getSalesOrderIdStr() {
        return salesOrderIdStr;
    }

    public void setSalesOrderIdStr(String salesOrderIdStr) {
        this.salesOrderIdStr = salesOrderIdStr;
    }

    public Double getSubtotal() {
        return subtotal;
    }

    public void setSubtotal(Double subtotal) {
        this.subtotal = subtotal;
    }

    public Double getTax() {
        return tax;
    }

    public void setTax(Double tax) {
        this.tax = tax;
    }

    public Double getTotal() {
        return total;
    }

    public void setTotal(Double total) {
        this.total = total;
    }

    public Boolean getCancelled() {
        return cancelled;
    }

    public void setCancelled(Boolean cancelled) {
        this.cancelled = cancelled;
    }

    public Boolean getPaymentMode() {
        return paymentMode;
    }

    public void setPaymentMode(Boolean paymentMode) {
        this.paymentMode = paymentMode;
    }
    
    
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof SalesOrder)) {
            return false;
        }
        SalesOrder other = (SalesOrder) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "merlion.crm.sopm.entity.SalesOrder[ id=" + id + " ]";
    }

    /**
     * @return the customer
     */
    public Customer getCustomer() {
        return customer;
    }

    /**
     * @param customer the customer to set
     */
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    /**
     * @return the purchaseOrder
     */
    public PurchaseOrder getPurchaseOrder() {
        return purchaseOrder;
    }

    /**
     * @param purchaseOrder the purchaseOrder to set
     */
    public void setPurchaseOrder(PurchaseOrder purchaseOrder) {
        this.purchaseOrder = purchaseOrder;
    }

    /**
     * @return the salesOrderDate
     */
    public Timestamp getSalesOrderDate() {
        return salesOrderDate;
    }

    /**
     * @param salesOrderDate the salesOrderDate to set
     */
    public void setSalesOrderDate(Timestamp salesOrderDate) {
        this.salesOrderDate = salesOrderDate;
    }

    public Boolean getFreightOnBoard() {
        return freightOnBoard;
    }

    public void setFreightOnBoard(Boolean freightOnBoard) {
        this.freightOnBoard = freightOnBoard;
    }

    public Boolean getFullShipment() {
        return fullShipment;
    }

    public void setFullShipment(Boolean fullShipment) {
        this.fullShipment = fullShipment;
    }

    public Collection<DeliveryOrder> getDeliveryOrders() {
        return deliveryOrders;
    }

    public void setDeliveryOrders(Collection<DeliveryOrder> deliveryOrders) {
        this.deliveryOrders = deliveryOrders;
    }

    /**
     * @return the indicativeLeadTime
     */
    public Timestamp getLeadTime() {
        return leadTime;
    }

    /**
     * @param indicativeLeadTime the indicativeLeadTime to set
     */
    public void setLeadTime(Timestamp leadTime) {
        this.leadTime = leadTime;
    }

    /**
     * @return the shipDate
     */
    public Timestamp getShipDate() {
        return shipDate;
    }

    /**
     * @param shipDate the shipDate to set
     */
    public void setShipDate(Timestamp shipDate) {
        this.shipDate = shipDate;
    }

    /**
     * @return the salesOrderStatus
     */
    public String getSalesOrderStatus() {
        return salesOrderStatus;
    }

    /**
     * @param salesOrderStatus the salesOrderStatus to set
     */
    public void setSalesOrderStatus(String salesOrderStatus) {
        this.salesOrderStatus = salesOrderStatus;
    }

    /**
     * @return the currency
     */
    public Boolean getCurrency() {
        return currency;
    }

    /**
     * @param currency the currency to set
     */
    public void setCurrency(Boolean currency) {
        this.currency = currency;
    }

    /**
     * @return the customerExecutive
     */
    public Staff getCustomerExecutive() {
        return customerExecutive;
    }

    /**
     * @param customerExecutive the customerExecutive to set
     */
    public void setCustomerExecutive(Staff customerExecutive) {
        this.customerExecutive = customerExecutive;
    }

    /**
     * @return the comments
     */
    public String getComments() {
        return comments;
    }

    /**
     * @param comments the comments to set
     */
    public void setComments(String comments) {
        this.comments = comments;
    }

    public Boolean getPromotion() {
        return promotion;
    }

    public void setPromotion(Boolean promotion) {
        this.promotion = promotion;
    }

    public Collection<ItemLine> getItemLines() {
        return itemLines;
    }

    public void setItemLines(Collection<ItemLine> itemLines) {
        this.itemLines = itemLines;
    }

    public Double getMemberDiscount() {
        return memberDiscount;
    }

    public void setMemberDiscount(Double memberDiscount) {
        this.memberDiscount = memberDiscount;
    }

    public Double getOrderDiscount() {
        return orderDiscount;
    }

    public void setOrderDiscount(Double orderDiscount) {
        this.orderDiscount = orderDiscount;
    }

    public Double getSpecialDiscount() {
        return specialDiscount;
    }

    public void setSpecialDiscount(Double specialDiscount) {
        this.specialDiscount = specialDiscount;
    }
    
}
